package com.pinyuana.dragongame.utils

import android.content.ContentResolver
import android.content.Context
import android.net.Uri
import android.provider.OpenableColumns
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.FormBody
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.logging.HttpLoggingInterceptor
import java.io.File
import java.io.IOException
import java.util.concurrent.TimeUnit


object HttpClientUtil {
    // 定义全局 OkHttpClient
    private val client: OkHttpClient

    init {
        // 创建日志拦截器（可选）
        val loggingInterceptor = HttpLoggingInterceptor().apply {
            level = HttpLoggingInterceptor.Level.BODY
        }

        // 初始化 OkHttpClient
        client = OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS) // 连接超时
            .readTimeout(30, TimeUnit.SECONDS)    // 读取超时
            .writeTimeout(30, TimeUnit.SECONDS)   // 写入超时
            .addInterceptor(loggingInterceptor)    // 添加日志拦截器
            // 你可以在这里添加更多的拦截器，例如全局请求头拦截器
            .build()
    }

    /**
     * GET 请求
     * @param url 请求的 URL
     * @param headers 请求头
     * @return Result 封装的响应数据或异常
     */
    suspend fun get(url: String, headers: Map<String, String>? = null): Result<String> {
        return withContext(Dispatchers.IO) {
            try {
                val requestBuilder = Request.Builder().url(url).get()

                // 添加请求头
                headers?.forEach { (key, value) ->
                    requestBuilder.addHeader(key, value)
                }

                val request = requestBuilder.build()
                val response = client.newCall(request).execute()

                if (response.isSuccessful) {
                    val body = response.body?.string() ?: ""
                    Result.success(body)
                } else {
                    Result.failure(IOException("请求失败，状态码：${response.code}"))
                }
            } catch (e: Exception) {
                Result.failure(e)
            }
        }
    }

    /**
     * POST 表单请求
     * @param url 请求的 URL
     * @param headers 请求头
     * @param params 表单参数
     * @return Result 封装的响应数据或异常
     */
    suspend fun postForm(
        url: String,
        headers: Map<String, String>? = null,
        params: Map<String, String>? = null
    ): Result<String> {
        return withContext(Dispatchers.IO) {
            try {
                val formBuilder = FormBody.Builder()
                params?.forEach { (key, value) ->
                    formBuilder.add(key, value)
                }
                val formBody = formBuilder.build()

                val requestBuilder = Request.Builder().url(url).post(formBody)

                // 添加请求头
                headers?.forEach { (key, value) ->
                    requestBuilder.addHeader(key, value)
                }

                val request = requestBuilder.build()
                val response = client.newCall(request).execute()

                if (response.isSuccessful) {
                    val body = response.body?.string() ?: ""
                    Result.success(body)
                } else {
                    Result.failure(IOException("请求失败，状态码：${response.code}"))
                }
            } catch (e: Exception) {
                Result.failure(e)
            }
        }
    }

    /**
     * POST JSON 请求
     * @param url 请求的 URL
     * @param headers 请求头
     * @param json JSON 字符串
     * @return Result 封装的响应数据或异常
     */
    suspend fun postJson(
        url: String,
        headers: Map<String, String>? = null,
        json: String
    ): Result<String> {
        return withContext(Dispatchers.IO) {
            try {
                val mediaType = "application/json; charset=utf-8".toMediaTypeOrNull()
                val requestBody = json.toRequestBody(mediaType)

                val requestBuilder = Request.Builder().url(url).post(requestBody)

                // 添加请求头
                headers?.forEach { (key, value) ->
                    requestBuilder.addHeader(key, value)
                }

                val request = requestBuilder.build()
                val response = client.newCall(request).execute()

                if (response.isSuccessful) {
                    val body = response.body?.string() ?: ""
                    Result.success(body)
                } else {
                    Result.failure(IOException("请求失败，状态码：${response.code}"))
                }
            } catch (e: Exception) {
                Result.failure(e)
            }
        }
    }

    /**
     * 上传文件（支持单文件和多文件）
     * @param url 请求的 URL
     * @param headers 请求头
     * @param files 要上传的文件列表
     * @param params 可选的表单参数
     * @return Result 封装的响应数据或异常
     */
    suspend fun uploadFile(
        context: Context,
        url: String,
        headers: Map<String, String>? = null,
        uris: List<Uri>,
        params: Map<String, String>? = null
    ): Result<String> {
        return withContext(Dispatchers.IO) {
            try {
                val multipartBuilder = MultipartBody.Builder().setType(MultipartBody.FORM)

                // 添加表单参数
                params?.forEach { (key, value) ->
                    multipartBuilder.addFormDataPart(key, value)
                }

                // 添加文件
                uris.forEach { uri ->
                    val contentResolver: ContentResolver = context.contentResolver
                    val mimeType = contentResolver.getType(uri) ?: "application/x-www-form-urlencoded"
                    val inputStream = contentResolver.openInputStream(uri)
                    val fileName = getFileName(contentResolver, uri) ?: "file"

                    if (inputStream != null) {
                        val bytes = inputStream.readBytes()
                        val requestBody = bytes.toRequestBody(mimeType.toMediaTypeOrNull())
                        multipartBuilder.addFormDataPart(
                            "file", // 根据后端接口要求修改
                            fileName,
                            requestBody
                        )
                        inputStream.close()
                    }
                }

                val requestBody = multipartBuilder.build()

                val requestBuilder = Request.Builder().url(url).post(requestBody)

                // 添加请求头
                headers?.forEach { (key, value) ->
                    requestBuilder.addHeader(key, value)
                }

                val request = requestBuilder.build()
                val response = client.newCall(request).execute()

                if (response.isSuccessful) {
                    val body = response.body?.string() ?: ""
                    Result.success(body)
                } else {
                    Result.failure(IOException("上传失败，状态码：${response.code}"))
                }
            } catch (e: Exception) {
                Result.failure(e)
            }
        }
    }

  /**
     * 上传文件（支持单文件和多文件）
     * @param url 请求的 URL
     * @param headers 请求头
     * @param files 要上传的文件列表
     * @param params 可选的表单参数
     * @return Result 封装的响应数据或异常
     */
    suspend fun uploadFileMore(
        context: Context,
        url: String,
        headers: Map<String, String>? = null,
        uris: List<Uri>,
        params: Map<String, String>? = null
    ): Result<String> {
        return withContext(Dispatchers.IO) {
            try {
                val multipartBuilder = MultipartBody.Builder().setType(MultipartBody.FORM)

                // 添加表单参数
                params?.forEach { (key, value) ->
                    multipartBuilder.addFormDataPart(key, value)
                }

                // 添加文件
                uris.forEach { uri ->
                    val contentResolver: ContentResolver = context.contentResolver
                    val mimeType = contentResolver.getType(uri) ?: "application/x-www-form-urlencoded"
                    val inputStream = contentResolver.openInputStream(uri)
                    val fileName = getFileName(contentResolver, uri) ?: "file"

                    if (inputStream != null) {
                        val bytes = inputStream.readBytes()
                        val requestBody = bytes.toRequestBody(mimeType.toMediaTypeOrNull())
                        multipartBuilder.addFormDataPart(
                            "files", // 根据后端接口要求修改
                            fileName,
                            requestBody
                        )
                        inputStream.close()
                    }
                }

                val requestBody = multipartBuilder.build()

                val requestBuilder = Request.Builder().url(url).post(requestBody)

                // 添加请求头
                headers?.forEach { (key, value) ->
                    requestBuilder.addHeader(key, value)
                }

                val request = requestBuilder.build()
                val response = client.newCall(request).execute()

                if (response.isSuccessful) {
                    val body = response.body?.string() ?: ""
                    Result.success(body)
                } else {
                    Result.failure(IOException("上传失败，状态码：${response.code}"))
                }
            } catch (e: Exception) {
                Result.failure(e)
            }
        }
    }

    private fun getFileName(contentResolver: ContentResolver, uri: Uri): String? {
        var name: String? = null
        val cursor = contentResolver.query(uri, null, null, null, null)
        cursor?.use {
            if (it.moveToFirst()) {
                val displayNameIndex = it.getColumnIndex(OpenableColumns.DISPLAY_NAME)
                if (displayNameIndex >= 0) {
                    name = it.getString(displayNameIndex)
                }
            }
        }
        return name
    }



    /**
     * 取消所有请求
     */
    fun cancelAll() {
        client.dispatcher.cancelAll()
    }

}